#pragma warning(disable: 4996)
#include <iostream>
#include <string>
#include <cstring>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

using namespace std;

uint16_t port = 18989;
string ip = "106.55.186.228";

int main() {
    WSAData wsd;
    // 启动WinSock，并初始化
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {
        cout << "WSAStartup failed!" << WSAGetLastError() <<endl;
        return -1;
    }
    else {
        cout << "WSAStartup success!" << endl;
    }

    // 创建套接字
    SOCKET client_socket = socket(AF_INET, SOCK_DGRAM, 0); // IPPROTO_UDP
    if (client_socket == SOCKET_ERROR) {
        cout << "socket failed!" << WSAGetLastError() << endl;
        return -1;
    }
    else {
        cout << "socket success!" << endl;
    }

    // 设置服务器地址
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.S_un.S_addr = inet_addr(ip.c_str());

#define BUF_SIZE 1024

    char buffer[BUF_SIZE] = {};
    string line;
    while (true) {
        // 开始发送数据
        cout << "Please Enter# ";
        getline(cin, line);

        int n = sendto(client_socket, line.c_str(), line.size(), 0, (struct sockaddr*)&server, sizeof(server));
        if (n < 0) {
            cerr << "sendto failed!" << WSAGetLastError() << endl;
            break;
        }

        // 接收数据
        struct sockaddr_in peer;
        int peer_len = sizeof(peer);
        memset(&peer, 0, sizeof(peer));
        n = recvfrom(client_socket, buffer, BUF_SIZE - 1, 0, (struct sockaddr*)&peer, &peer_len);
        if (n > 0) {
            buffer[n] = '\0';
            cout << "Server Echo# " << buffer << endl;
        }
        else {
            cerr << "recvfrom failed!" << WSAGetLastError() << endl;
            break;
        }
    }

#undef BUF_SIZE

    // 关闭套接字
    closesocket(client_socket);
    WSACleanup();
    
    return 0;
}